#include "htf_ai_interface.h"
#include "core/htf_context.h"
#include "backend/htf_ai_backend_factory.h"
#include "backend/mindspore/htf_ms_backend.h" 
#include "utils/htf_url_parser.h"
#include "utils/htf_logger.h"
#include <stdlib.h>

struct htf_ai_handle {
    htf_context_t* ctx;
    htf_ai_backend_t* backend;
};

htf_ai_handle_t* htf_ai_create(const char* model_path) {
    if (!model_path) return NULL;

    htf_model_config_t config = {0};
    if (htf_parse_model_url(model_path, &config) != 0) {
        HTF_LOG_ERROR("Failed to parse model URL: %s", model_path);
        return NULL;
    }

    htf_ai_handle_t* h = (htf_ai_handle_t*)calloc(1, sizeof(htf_ai_handle_t));
    if (!h) return NULL;

    h->ctx = htf_context_create(config.backend_type);
    if (!h->ctx) goto fail;

    h->backend = htf_ai_backend_create(config.backend_type);
    if (!h->backend) goto fail;

    // Set the key and size before init (required only for MindSpore（lite）)
    if (config.backend_type == HTF_BACKEND_MINDSPORE) {
        if (htf_ms_backend_set_config(h->backend->impl,
                                      config.key, config.key_len,
                                      config.input_size, config.output_size) != 0) {
            HTF_LOG_ERROR("Failed to set MindSpore config");
            goto fail;
        }
    }

    if (h->backend->ops->init(h->backend->impl, config.base_path) != 0) {
        HTF_LOG_ERROR("Backend init failed for %s", config.base_path);
        goto fail;
    }

    HTF_LOG_INFO("AI handle created for %s (backend=%d)", config.base_path, config.backend_type);
    return h;

fail:
    if (h->backend) htf_ai_backend_destroy(h->backend);
    if (h->ctx) htf_context_destroy(h->ctx);
    free(h);
    return NULL;
}

int htf_ai_infer(htf_ai_handle_t* handle,
                 const float* input, size_t input_size,
                 float* output, size_t output_size) {
    if (!handle || !handle->backend || !input || !output) return -1;
    return handle->backend->ops->run(handle->backend->impl, input, output);
}

void htf_ai_destroy(htf_ai_handle_t* handle) {
    if (!handle) return;
    htf_ai_backend_destroy(handle->backend);
    htf_context_destroy(handle->ctx);
    free(handle);
}